import UIKit
import AVFoundation
import CoreImage
import Metal
import CoreMedia
import MetalKit

class YCFilterManager {
    // MARK: - Properties
    static let shared = YCFilterManager()
    
    // 基础属性
    private let context: CIContext
    
    // Metal相关属性
    private let metalDevice: MTLDevice?
    private let commandQueue: MTLCommandQueue?
    private let metalContext: CIContext?
    
    // 性能相关
    private let processingQueue = DispatchQueue(label: "com.yccamera.filterprocessing", qos: .userInteractive)
    private var useMetalAcceleration = true // 默认启用Metal加速
    private var renderSemaphore = DispatchSemaphore(value: 3) // 限制并发渲染数量
    
    // 设备能力检测
    public let isMetalSupported: Bool
    
    // 预览图像处理的时间和缓存相关属性
    private var lastPreviewProcessTime: CFTimeInterval = 0
    private var lastProcessedPreviewImage: CIImage?
    private var autoEnhanceEnabled: Bool = false
    private var shadowsBoosted: Bool = false
    private var highlightsReduced: Bool = false
    
    // 滤镜相关
    private var filters: [YCFilter]
    private var currentFilterIndex = 0
    private var currentFilterParameters: FilterParameters {
        get { return filters[currentFilterIndex].parameters }
        set { filters[currentFilterIndex].parameters = newValue }
    }
    
    private var currentFilter: YCFilter {
        return filters[currentFilterIndex]
    }
    
    // MARK: - Initialization
    private init() {
        // 设置Metal设备和命令队列
        self.metalDevice = MTLCreateSystemDefaultDevice()
        self.commandQueue = metalDevice?.makeCommandQueue()
        
        // 设备能力检测
        self.isMetalSupported = metalDevice != nil
        
        // 创建优化的Metal上下文
        if let device = metalDevice {
            let options: [CIContextOption: Any] = [
                .workingFormat: CIFormat.RGBA8,
                .outputColorSpace: CGColorSpaceCreateDeviceRGB(),
                .workingColorSpace: CGColorSpaceCreateDeviceRGB(),
                .useSoftwareRenderer: false,
                .priorityRequestLow: false,
                .cacheIntermediates: false
            ]
            self.metalContext = CIContext(mtlDevice: device, options: options)
        } else {
            self.metalContext = nil
            print("警告: Metal设备不可用，将使用CPU渲染")
        }
        
        // 初始化标准CIContext
        self.context = CIContext(options: [
            .workingFormat: CIFormat.RGBA8,
            .outputColorSpace: CGColorSpaceCreateDeviceRGB(),
            .workingColorSpace: CGColorSpaceCreateDeviceRGB(),
            .cacheIntermediates: false
        ])
        
        // 加载所有滤镜
        self.filters = YCFilterFactory.shared.getAllFilters()
    }
    
    // MARK: - Public Methods
    func nextFilter() {
        currentFilterIndex = (currentFilterIndex + 1) % filters.count
        lastProcessedPreviewImage = nil
    }
    
    func previousFilter() {
        currentFilterIndex = (currentFilterIndex - 1 + filters.count) % filters.count
        lastProcessedPreviewImage = nil
    }
    
    func getCurrentFilterName() -> String {
        return currentFilter.name
    }
    
    func getAllFilterNames() -> [String] {
        return filters.map { $0.name }
    }
    
    func setFilter(by name: String) {
        if let index = filters.firstIndex(where: { $0.name == name }) {
            currentFilterIndex = index
            lastProcessedPreviewImage = nil
        }
    }
    
    // MARK: - Image Processing Methods
    func processPreviewImage(_ image: CIImage) -> CIImage? {
        // 如果是原图且没有其他效果，直接返回
        guard currentFilter.type != .none || 
              autoEnhanceEnabled || shadowsBoosted || highlightsReduced else {
            return image
        }
        
        var resultImage = image
        
        autoreleasepool {
            // 应用当前滤镜
            if currentFilter.type != .none {
                // 每一帧都重新处理，不使用缓存
                if useMetalAcceleration && metalDevice != nil && 
                   currentFilter.effect.supportsMetalAcceleration() {
                    if let metalProcessed = processWithMetal(resultImage) {
                        resultImage = metalProcessed
                    } else if let processed = applySingleFilter(to: resultImage) {
                        resultImage = processed
                    }
                } else if let processed = applySingleFilter(to: resultImage) {
                    resultImage = processed
                }
            }
            
            // 应用图像增强
            if autoEnhanceEnabled {
                if let enhanced = applyAutoEnhance(to: resultImage) {
                    resultImage = enhanced
                }
            }
            
            if shadowsBoosted {
                if let shadowsAdjusted = boostShadows(in: resultImage) {
                    resultImage = shadowsAdjusted
                }
            }
            
            if highlightsReduced {
                if let highlightsAdjusted = reduceHighlights(in: resultImage) {
                    resultImage = highlightsAdjusted
                }
            }
            
            // 确保输出图像尺寸与输入一致
            if resultImage.extent.size != image.extent.size {
                resultImage = resultImage.transformed(by: CGAffineTransform(
                    scaleX: image.extent.size.width / resultImage.extent.size.width,
                    y: image.extent.size.height / resultImage.extent.size.height
                ))
            }
        }
        
        return resultImage
    }
    
    func processCapturedImage(_ image: CIImage, orientation: AVCaptureVideoOrientation, isFrontCamera: Bool = false) -> UIImage? {
        
        print("📸 拍照处理 - 原始图像尺寸: \(image.extent.width) x \(image.extent.height)")
        
        // 1. 应用滤镜
        var processedImage: CIImage
        if let filtered = applySingleFilter(to: image) {
            processedImage = filtered
            print("📸 滤镜处理后尺寸: \(processedImage.extent.width) x \(processedImage.extent.height)")
        } else {
            processedImage = image
        }
        
        // 2. 创建CGImage
        let imageRect = processedImage.extent
        // ⚠️ 关键：保存照片时使用 scale = 1.0，保持完整分辨率
        let scale: CGFloat = 1.0  // 不使用屏幕scale，避免降低图像分辨率
        
        print("📸 创建CGImage - extent: \(imageRect.width) x \(imageRect.height), scale: \(scale)")
        
        guard let cgImage = context.createCGImage(processedImage,
                                                from: imageRect,
                                                format: .RGBA8,
                                                colorSpace: CGColorSpaceCreateDeviceRGB()) else {
            return nil
        }
        
        print("📸 CGImage尺寸: \(cgImage.width) x \(cgImage.height)")
        
        // 3. 处理方向和镜像
        var finalOrientation: UIImage.Orientation
        
        if isFrontCamera {
            // 前置摄像头：结合方向和镜像
            switch orientation {
            case .portrait:
                finalOrientation = .leftMirrored  // 左镜像 = 右旋转 + 水平翻转
            case .portraitUpsideDown:
                finalOrientation = .rightMirrored  // 右镜像 = 左旋转 + 水平翻转
            case .landscapeRight:
                finalOrientation = .upMirrored  // 上镜像 = 无旋转 + 水平翻转
            case .landscapeLeft:
                finalOrientation = .downMirrored  // 下镜像 = 180度 + 水平翻转
            @unknown default:
                finalOrientation = .leftMirrored
            }
        } else {
            // 后置摄像头：只处理方向
            switch orientation {
            case .portrait:
                finalOrientation = .right
            case .portraitUpsideDown:
                finalOrientation = .left
            case .landscapeRight:
                finalOrientation = .up
            case .landscapeLeft:
                finalOrientation = .down
            @unknown default:
                finalOrientation = .right
            }
        }
        
        // 4. 创建最终的 UIImage
        return UIImage(cgImage: cgImage, scale: scale, orientation: finalOrientation)
    }
    
    // MARK: - Private Methods
    private func processWithMetal(_ image: CIImage) -> CIImage? {
        guard let device = metalDevice,
              let commandQueue = commandQueue,
              let metalContext = metalContext else {
            return applySingleFilter(to: image)
        }
        
        // 创建命令缓冲区
        guard let commandBuffer = commandQueue.makeCommandBuffer() else {
            return applySingleFilter(to: image)
        }
        
        // 获取图像尺寸
        let imageSize = image.extent.size
        
        // 创建纹理描述符
        let textureDescriptor = MTLTextureDescriptor.texture2DDescriptor(
            pixelFormat: .rgba8Unorm,
            width: Int(imageSize.width),
            height: Int(imageSize.height),
            mipmapped: false
        )
        textureDescriptor.usage = [.shaderRead, .shaderWrite, .renderTarget]
        textureDescriptor.storageMode = .private
        
        // 创建输出纹理
        guard let outputTexture = device.makeTexture(descriptor: textureDescriptor) else {
            return applySingleFilter(to: image)
        }
        
        // 应用滤镜效果
        let result = currentFilter.effect.applyMetal(to: image,
                                                   with: currentFilter.parameters,
                                                   device: device,
                                                   commandQueue: commandQueue)
        
        // 如果Metal处理失败，回退到CoreImage处理
        guard let filteredImage = result else {
            return applySingleFilter(to: image)
        }
        
        // 渲染到输出纹理
        metalContext.render(filteredImage,
                           to: outputTexture,
                           commandBuffer: commandBuffer,
                           bounds: filteredImage.extent,
                           colorSpace: CGColorSpaceCreateDeviceRGB())
        
        // 提交命令缓冲区并等待完成
        commandBuffer.commit()
        commandBuffer.waitUntilCompleted()
        
        // 从输出纹理创建新的CIImage
        if let outputImage = CIImage(mtlTexture: outputTexture,
                                    options: [.colorSpace: CGColorSpaceCreateDeviceRGB()]) {
            return outputImage
        }
        
        return filteredImage
    }
    
    private func applySingleFilter(to image: CIImage) -> CIImage? {
        // 每次都重新应用滤镜，不使用缓存
        return currentFilter.effect.apply(to: image,
                                        with: currentFilter.parameters,
                                        context: context)
    }
    
    // MARK: - Enhancement Methods
    private func applyAutoEnhance(to image: CIImage) -> CIImage? {
        guard let filter = CIFilter(name: "CIAutoEnhance") else { return image }
        filter.setValue(image, forKey: kCIInputImageKey)
        return filter.outputImage
    }
    
    private func boostShadows(in image: CIImage) -> CIImage? {
        guard let filter = CIFilter(name: "CIGammaAdjust") else { return image }
        filter.setValue(image, forKey: kCIInputImageKey)
        filter.setValue(0.85, forKey: "inputPower")
        return filter.outputImage
    }
    
    private func reduceHighlights(in image: CIImage) -> CIImage? {
        guard let filter = CIFilter(name: "CIHighlightShadowAdjust") else { return image }
        filter.setValue(image, forKey: kCIInputImageKey)
        filter.setValue(0.7, forKey: "inputHighlightAmount")
        return filter.outputImage
    }
    
    // MARK: - Parameter Adjustment Methods
    func adjustBrightness(_ brightness: Float) {
        var params = currentFilterParameters
        params.brightness = brightness
        currentFilterParameters = params
        lastProcessedPreviewImage = nil
    }
    
    func adjustContrast(_ contrast: Float) {
        var params = currentFilterParameters
        params.contrast = contrast
        currentFilterParameters = params
        lastProcessedPreviewImage = nil
    }
    
    func adjustSaturation(_ saturation: Float) {
        var params = currentFilterParameters
        params.saturation = saturation
        currentFilterParameters = params
        lastProcessedPreviewImage = nil
    }
    
    func adjustTemperature(_ temperature: Float) {
        var params = currentFilterParameters
        params.temperature = temperature
        currentFilterParameters = params
        lastProcessedPreviewImage = nil
    }
    
    func resetCurrentFilterParameters() {
        filters[currentFilterIndex] = YCFilterFactory.shared.createFilter(type: currentFilter.type)
        lastProcessedPreviewImage = nil
    }
    
    // MARK: - Cleanup
    deinit {
        // 清理资源
    }
}

